#ifndef __COMMON_MESSAGE__
#define __COMMON_MESSAGE__

#include "..\Common\CommonNetwork.h"
#include "..\Common\CommonObject.h"

// about Service..
enum SERVICE_MESSAGE			
{
	S_REQUEST_CODE			= 1,
	S_REQUEST_CLIENT,
	S_REQUEST_OBJECT,
	S_REQUEST_RELAY_LINK,
	S_NOTICE_NEW_OBJECT,
	S_NOTICE_DEL_OBJECT,
	S_NOTICE_ACCESS_OFF,
	S_NOTICE_MESSAGE,
	S_NOTICE_MISSILE_CRUSH,

	SR_REQUEST_CODE			= S_REQUEST_CODE + 50,		
	SR_REQUEST_CLIENT,
	SR_REQUEST_OBJECT,
	SR_REQUEST_RELAY_LINK,
	SR_NOTICE_NEW_OBJECT,
	SR_NOTICE_DEL_OBJECT,
	SR_NOTICE_ACCESS_OFF,
	SR_NOTICE_MESSAGE,
	SR_NOTICE_MISSILE_CRUSH
};

struct service_msg_base {
	virtual ~service_msg_base(void) { }
};

// S_REQUEST_CODE
struct service_msg_REQUEST_CODE : public service_msg_base {	 
};
struct service_msg_REQUEST_CODE_RETURN : public service_msg_base {
	unsigned int ClientCode;
};

// S_REQUEST_CLIENT
struct service_msg_REQUEST_CLIENT : public service_msg_base {	
};
struct service_msg_REQUEST_CLIENT_RETURN : public service_msg_base {
	struct client_info {
		ip				IP;
		unsigned int	ClientCode;
		unsigned int	UdpPort;	
	};

	unsigned int ClientNumber;
	client_info* ExtraData;	// client_info array data.
};

// S_REQUEST_OBJECT
struct service_msg_REQUEST_OBJECT : public service_msg_base {	
};
struct service_msg_REQUEST_OBJECT_RETURN : public service_msg_base {	
	struct object_info
	{
		unsigned int	ObjectID;	
		OBJECT_TYPE		ObjectType;
		unsigned int	OwnerCode;
		int				ObjectExtraLength;
		extra_3d_object ObjectExtra;		//if object data changed, this change max object structure.
		//char*			ObjectExtraData;
	};

	unsigned int ObjectNumber;
	object_info *ExtraData;	
};


struct service_msg_REQUEST_RELAY_LINK : public service_msg_base {
};
struct service_msg_REQUEST_RELAY_LINK_RETURN : public service_msg_base {
	bool Result;
};

// S_NOTICE_NEW_OBJECT
struct service_msg_NOTICE_NEW_OBJECT : public service_msg_base {	
	OBJECT_TYPE		ObjectType;
	unsigned int	OwnerCode;
	unsigned int	ExtraLength;
	char*			ExtraPtr;		// object's extra data. (ex. position, rotation)
};
struct service_msg_NOTICE_NEW_OBJECT_RETURN : public service_msg_base {		
};

// S_NOTICE_DEL_OBJECT
struct service_msg_NOTICE_DEL_OBJECT : public service_msg_base {		
	unsigned int	ObjectID;	
};
struct service_msg_NOTICE_DEL_OBJECT_RETURN : public service_msg_base {		
};

// S_NOTICE_ACCESS_OFF
struct service_msg_NOTICE_ACCESS_OFF : public service_msg_base {		
	unsigned int	ClientID;	
};
struct service_msg_NOTICE_ACCESS_OFF_RETURN : public service_msg_base {		
};

// S_NOTICE_MESSAGE
struct service_msg_NOTICE_MESSAGE : public service_msg_base {		
	unsigned int	MsgLength;	// string is wide character. so length is x2.
	char*			MsgString;	
};
struct service_msg_NOTICE_MESSAGE_RETURN : public service_msg_base {		
};

// S_NOTICE_MISSILE_CRUSH
struct service_msg_NOTICE_MISSILE_CRUSH : public service_msg_base {		
	unsigned int MissileOwner;
	unsigned int MissileId;
	unsigned int TargetClient;
};
struct service_msg_NOTICE_MISSILE_CRUSH_RETURN : public service_msg_base {		
};



// about broadcast...
enum BRODCAST_MESSAGE
{
	B_NEW_CLIENT	= 100,
	B_OFF_CLIENT,
	B_NEW_OBJECT,			// have extra data.
	B_DEL_OBJECT,
	B_MESSAGE,				// have extra data.
	B_CHECK_SOCKET,
	B_MISSILE_CRUSH
};

struct broadcast_msg_base {
	virtual ~broadcast_msg_base(void) { }	
};

struct broadcast_msg_NEW_CLIENT : public broadcast_msg_base {
	ip				IP;
	unsigned int	ClientCode;
	unsigned int	UdpPort;	
};

struct broadcast_msg_OFF_CLIENT : public broadcast_msg_base {
	unsigned int	ClientCode;
};

struct broadcast_msg_NEW_OBJECT : public broadcast_msg_base {
	unsigned int	ObjectID;
	OBJECT_TYPE		ObjectType;
	unsigned int	OwnerCode;
	unsigned int	ExtraLength;
	char*			ExtraPtr;		// object extra data. it same to Service's Notice New Object Message extra data.
};

struct broadcast_msg_DEL_OBJECT : public broadcast_msg_base {
	unsigned int	ObjectID;
};

struct broadcast_msg_MESSAGE : public broadcast_msg_base {
	unsigned int	MsgLength;		// same to Service's Notice Message.
	char*			MsgString;
};

struct broadcast_msg_CHECK_SOCKET : public broadcast_msg_base {
};

struct broadcast_msg_MISSILE_CRUSH : public broadcast_msg_base {
	unsigned int MissileOwner;
	unsigned int MissileId;
	unsigned int TargetClient;
};



enum SYNC_TYPE {
	ST_LINK_UDP,
	ST_OBJECT,
};

const int BORDER_COUNTER = 300;	// Client's UdpLinkThread Max Sending Count.

struct sync_link {		//  ST_LINK_UDP Data. For connect udp.
	SYNC_TYPE SyncType;
	unsigned int ClienetCode;	
	int TotalCount;
};

struct sync_object_3d {	// object sync data.
	SYNC_TYPE		SyncType;
	OBJECT_TYPE		ObjectType;
	unsigned int	OwnerCode;
	unsigned int	ObjectCode;
	unsigned int	SendTick;	
	extra_3d_object SyncData;
};

const int MAX_SYNC_LENGTH = sizeof(sync_object_3d);

#endif